home *** CD-ROM | disk | FTP | other *** search
- PROGRAM Rotate_A_BitMap____VERY_SLOWLY___but_with_scaling;
-
- {
- Written by John Paul D'India (from D'India Software)
-
- Since I'm writing this, I'm gonna have to suggest you guys go out and
- download DARKWOLF. Here's my little ad =)
-
- ╔════════════════════════╡ D'India Software ╞═══════════════════════╗
- ║ ▀▄▄▄▄▄▄▄▄ ▄ ▄ ▄▄ ║
- ║ █ ▀▀▄ ▀▄ █ ▄ ▄▀ ▀ ║
- ║ █ ▀▄ █ █ █ █ █ ║
- ║ █ █ █ ▄ ▀▄ █ █ █ ║
- ║ █ █ ▄▄▄ █▄▀▄ █▄▄▀ █ █ ▄▄▄ █ ▄█▄▄ ║
- ║ █ ▄▀ ▄▀ █ █ █ ▀▄ █ ▄ █ █ █ █ █ ║
- ║ ▀ ▄▄▀ █ █ █ █ █ ▀▄ █ ▀▄ █ █ █ █ █ ║
- ║ ▄▄▀▀▀ ▀▀▀▀▀ ▀ ▄▀ ▀▄ ▀▄ █ ▀▄ █ ▀▀▀ ▀ █ ║
- ║ ▀▀▀ ▀ ▀ ▀ ║
- ╠═══════════════════════════════════════════════════════════════════╣
- ║ D'India Software's latest SHAREWARE masterpiece! DARKWOLF, the ║
- ║ action game with awesome 256 color VGA graphics, digital sound, ║
- ║ digital music, 32-bit parallax scrolling, and more! The "play ║
- ║ control" and "fun factor" are impressive! As the king's wizard, ║
- ║ you must try and keep the kingdom from being thrown into civil ║
- ║ war, but beware Grondahl Morrison is out to shorten your lifespan.║
- ║ CHECK IT OUT!! ║
- ╚═══════════════════════════════════════════════════════════════════╝
-
-
- This program demonstrates simple rotation in PASCAL!
- It first calculates the four corners of the bitmap.
-
- P1
- ■
- / \
- / \
- / \
- P3 ■ ■ P2
- \ /
- \ /
- \ /
- ■
- P4
-
- Then, going down from P1 to P3 the program draws lines with a P1-P2 slope.
- It indexes into the bitmap to find the proper color.
-
- Things could be GREATLY speeded up by replacing
- - PutPixel ( X,Y,Mem[Seg(Buf):Ofs(Buf)+(BitMap_Pos * W) div BitMap_Dif] );
- with a faster method.
-
- One suggestion is to simply change the inner line loop as follows
- PutPixel ( X,Y,Mem[Seg(Buf):Ofs(Buf)+BitMap_Pos] );
- for x:=x1+1 to x2 do
- begin
- if ( d >= 0 ) then
- begin
- PutPixel ( X,Y,Mem[Seg(Buf):Ofs(Buf)+BitMap_Pos] );
- inc( y, yincr );
- inc( d, aincr );
- end
- else
- inc( d, bincr );
- Inc ( BitMap_Pos,BitMap_Dir );
- PutPixel ( X,Y,Mem[Seg(Buf):Ofs(Buf)+BitMap_Pos] );
- end;
- This should give you descent accuracy, and it will make the procedure way
- faster. You also have to initialize BitMap_Pos to W and not BitMap_Dif!
-
- The important thing to remember is that there are many different techniques
- to drawing a line. This is just one (slow) approach. However please
- remember it is still way faster than rotating each point individually, AND
- it DOES scale!
-
- }
-
- Const
- Sine_Cosine_Precision = 128;
- Max_Size = 140;
- Min_Size = 20;
-
-
- Var Angle : Integer;
- Cosine : Array[0..359] of Integer;
- Sine : Array[0..359] of Integer;
- BitMap_Width : Word;
- BitMap_Heigth : Word;
- BitMap : Pointer;
- F : File;
- RGB : Array[1..768] of Byte;
- Scr : Pointer;
-
- Size : Integer;
- SizeDir : Integer;
-
-
- {────────────────────────────────────────────────────────────────────────────}
-
-
- PROCEDURE PutPixel ( X,Y,Col : Integer );
- BEGIN
- Mem[Seg(Scr^):Ofs(Scr^)+Y*320+X] := Col;
- END;
-
-
- {────────────────────────────────────────────────────────────────────────────}
-
-
- PROCEDURE Line_Copy ( Var Buf;W,X1,Y1,X2,Y2 : Integer );
-
- var d, dx, dy,
- aincr, bincr,
- xincr, yincr,
- x, y : integer;
- BitMap_Pos : Integer;
- BitMap_Dir : Integer;
- BitMap_Dif : Integer;
-
-
- procedure SwapInt( var i1, i2: integer );
- var dummy : integer;
- begin
- dummy := i2;
- i2 := i1;
- i1 := dummy;
- end;
-
-
- begin
- if ( abs(x2-x1) < abs(y2-y1) ) then
- begin
- BitMap_Dif := abs(x2-X1)+abs(y2-y1);
- if ( y1 > y2 ) then
- begin
- SwapInt( x1, x2 );
- SwapInt( y1, y2 );
- BitMap_Dir := -1;
- BitMap_Pos := BitMap_Dif;
- end else
- BEGIN
- BitMap_Dir := 1;
- BitMap_Pos := 0;
- END;
-
- if ( x2 > x1 ) then xincr := 1
- else xincr := -1;
-
- dy := y2 - y1;
- dx := abs( x2-x1 );
- d := 2 * dx - dy;
- aincr := 2 * (dx - dy);
- bincr := 2 * dx;
- x := x1;
- y := y1;
-
- PutPixel ( X,Y,Mem[Seg(Buf):Ofs(Buf)+(BitMap_Pos * W) div BitMap_Dif] );
- for y:=y1+1 to y2 do { Execute line on Y-axes }
- begin
- if ( d >= 0 ) then
- begin
- Inc ( BitMap_Pos,BitMap_Dir );
- PutPixel ( X,Y,Mem[Seg(Buf):Ofs(Buf)+(BitMap_Pos * W) div BitMap_Dif] );
- inc( x, xincr );
- inc( d, aincr );
- end
- else
- inc( d, bincr );
- Inc ( BitMap_Pos,BitMap_Dir );
- PutPixel ( X,Y,Mem[Seg(Buf):Ofs(Buf)+(BitMap_Pos * W) div BitMap_Dif] );
- end;
- end
- else { Check X-axes }
- begin
- BitMap_Dif := abs(x2-X1)+abs(y2-y1);
- if ( x1 > x2 ) then { x1 > x2? }
- begin
- SwapInt( x1, x2 ); { Yes --> Swap X1 with X2 }
- SwapInt( y1, y2 ); { and Y1 with Y2 }
- BitMap_Dir := -1;
- BitMap_Pos := BitMap_Dif;
- end else
- BEGIN
- BitMap_Dir := 1;
- BitMap_Pos := 0;
- END;
-
- if ( y2 > y1 ) then yincr := 1 { Set Y-axis increment }
- else yincr := -1;
-
- dx := x2 - x1;
- dy := abs( y2-y1 );
- d := 2 * dy - dx;
- aincr := 2 * (dy - dx);
- bincr := 2 * dy;
- x := x1;
- y := y1;
-
- PutPixel ( X,Y,Mem[Seg(Buf):Ofs(Buf)+(BitMap_Pos * W) div BitMap_Dif] );
- for x:=x1+1 to x2 do { Execute line on X-axes }
- begin
- if ( d >= 0 ) then
- begin
- Inc ( BitMap_Pos,BitMap_Dir );
- PutPixel ( X,Y,Mem[Seg(Buf):Ofs(Buf)+(BitMap_Pos * W) div BitMap_Dif] );
- inc( y, yincr );
- inc( d, aincr );
- end
- else
- inc( d, bincr );
- Inc ( BitMap_Pos,BitMap_Dir );
- PutPixel ( X,Y,Mem[Seg(Buf):Ofs(Buf)+(BitMap_Pos * W) div BitMap_Dif] );
- end;
-
- end;
-
- END;
-
-
- {────────────────────────────────────────────────────────────────────────────}
-
-
- PROCEDURE Rotate ( Var Buf;OldW,OldH,W,H,X,Y,Angle : Integer );
- Var X1,Y1,X2,Y2,X3,Y3,X4,Y4 : Integer;
- HalfH,HalfW : Integer;
- DeltaX,DeltaY : Integer;
- TY : Integer;
- BEGIN
- {
- P1(X1,Y1) P2(X2,Y2)
- ■ ■
-
-
-
- ■ ■
- P3(X3,Y3) P4(X4,Y4)
-
- }
- HalfH := H Shr 1;
- HalfW := W Shr 1;
- X1 := X+((-HalfW*Cosine[Angle])-(+HalfH*Sine[Angle])) DIV Sine_Cosine_Precision;
- X2 := X+((+HalfW*Cosine[Angle])-(+HalfH*Sine[Angle])) DIV Sine_Cosine_Precision;
- X3 := X+((-HalfW*Cosine[Angle])-(-HalfH*Sine[Angle])) DIV Sine_Cosine_Precision;
- X4 := X+((+HalfW*Cosine[Angle])-(-HalfH*Sine[Angle])) DIV Sine_Cosine_Precision;
-
- Y1 := Y+((-HalfW*Sine[Angle])+(+HalfH*Cosine[Angle])) DIV Sine_Cosine_Precision;
- Y2 := Y+((+HalfW*Sine[Angle])+(+HalfH*Cosine[Angle])) DIV Sine_Cosine_Precision;
- Y3 := Y+((-HalfW*Sine[Angle])+(-HalfH*Cosine[Angle])) DIV Sine_Cosine_Precision;
- Y4 := Y+((+HalfW*Sine[Angle])+(-HalfH*Cosine[Angle])) DIV Sine_Cosine_Precision;
-
- DeltaY := Y3-Y1;
- DeltaX := X3-X1; { ■ P1(X1,Y1) }
- For TY := 0 to pred(H) do { / }
- BEGIN { / }
- { / }
- X := DeltaX*TY Div H; { ■ P3(X3,Y3) }
- Y := DeltaY*TY Div H; { SubX := DeltaX*TY div H }
- { SubY := DeltaY*TY div H }
- Line_Copy ( Mem[Seg(Buf):Ofs(Buf)+(TY*OldH div H)*OldW],OldW,X2+X,Y2+Y,X1+X,Y1+Y );
- END;
- END;
-
-
- {────────────────────────────────────────────────────────────────────────────}
-
-
- PROCEDURE Make_Sine_Cosine_Table;
- Var I : Integer;
- BEGIN
- For I := 0 to 359 do
- BEGIN
- Sine[I] := Round(Sin(I*3.14159265/180)*Sine_Cosine_Precision);
- Cosine[I] := Round(Cos(I*3.14159265/180)*Sine_Cosine_Precision);
- END;
- END;
-
-
- {────────────────────────────────────────────────────────────────────────────}
-
-
- PROCEDURE SETRGBBLOCK ( C,CNT : WORD;VAR BUF ); ASSEMBLER;
- ASM
- PUSH DS
- CLD
- LDS SI,BUF { LOAD BUF INTO DS:SI }
- MOV CX,CNT { GET NUMBER OF COLORS TO SET }
- MOV AX,3 { MULTIPLY BY 3 FOR R,G,B }
- MUL CX
- MOV CX,AX { STORE IN COUNT REG }
- MOV DX,3C8H { PEL WRITE MODE }
- MOV AX,C
- OUT DX,AL { WRITE COLOR NUMBER TO DAC }
-
- INC DX
- JCXZ @SKIP
- REP OUTSB
- @SKIP:
-
- POP DS
- END;
-
-
- {────────────────────────────────────────────────────────────────────────────}
-
-
- BEGIN
- Asm
- Mov AX,13h
- Int 10h
- End;
-
- Assign ( F,'D''India.Cel' );
- Reset ( F,1 );
- Seek ( F,2 );
- Blockread ( F,BitMap_Width,2 );
- Blockread ( F,BitMap_Heigth,2 );
- Seek ( F,32 );
- Blockread ( F,RGB,Sizeof(RGB) );
- RGB[255*3+2] := 42;
- RGB[255*3+1] := 0;
- RGB[255*3+0] := 0;
- SetRGBBlock ( 0,256,RGB );
- Getmem ( BitMap,BitMap_Heigth*BitMap_Width );
- Blockread ( F,BitMap^,BitMap_Heigth*BitMap_Width );
- Close ( F );
-
- Make_Sine_Cosine_Table;
-
- GetMem ( Scr,64000 );
-
- Angle := 0;
- Size := Min_Size;
- SizeDir := 1;
- Repeat
- Angle := (Angle+4) MOD 360;
- Fillchar ( Scr^,64000,0 );
- Inc ( Size,SizeDir );
- If Size > Max_Size then SizeDir := -SizeDir else
- If Size < Min_Size then SizeDir := -SizeDir;
- Rotate ( BitMap^,BitMap_Width,BitMap_Heigth,
- BitMap_Width*Size div 100,
- BitMap_Heigth*Size div 100,
- 160,100,
- Angle );
- Move ( Scr^,Mem[$A000:$0000],64000 );
- Until Port[$60] = 129;
-
- FreeMem ( Scr,64000 );
-
- Asm
- Mov AX,03h
- Int 10h
- End;
- END.